// creazione di una classe generica per stack


#include <iostream>
using namespace std;

const int SIZE = 100;

// creazione della classe generica stack
template <class StackType> class stack {
	StackType stck[SIZE];
	int tos; // indice della cima dello stack

public:
	stack() {tos = 0;}
	void push(StackType ob);
	StackType pop();
};

// push di un oggetto nello stack
template <class StackType> void stack<StackType>::push(StackType ob)
{
	if(tos==SIZE) {
		cout << "Lo stack e' pieno.\n";
		return;
	}
	stck[tos] = ob;
	tos++;
}

// pop di un oggetto dallo stack
template <class StackType> StackType stack<StackType>::pop()
{
	if(tos==0) {
		cout << "Lo stack e' vuoto.\n";
		return 0;
	}
	tos--;
	return stck[tos];
}


int main()
{
	// dimostra l'uso degli stack di caratteri
	stack<char> s1, s2;	// crea due stack di caratteri

	int i;

	s1.push('a');
	s2.push('x');
	s1.push('b');
	s2.push('y');
	s1.push('c');
	s2.push('z');

	for(i=0; i<3; i++) cout << "Pop s1: " << s1.pop() << "\n";
	for(i=0; i<3; i++) cout << "Pop s2: " << s2.pop() << "\n";

	// dimostra l'uso degli stack di double
	stack<double> ds1, ds2;	// crea due stack di double
	ds1.push(1.1);
	ds2.push(2.2);
	ds1.push(3.3);
	ds2.push(4.4);
	ds1.push(5.5);
	ds2.push(6.6);

	for(i=0; i<3; i++) cout << "Pop ds1: " << ds1.pop() << "\n";
	for(i=0; i<3; i++) cout << "Pop ds2: " << ds2.pop() << "\n";

	return 0;
}